﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

namespace ReactiveCode.Expressions
{
    using Observables;

    class ReturnExpression<T>: ReactiveExpression
    {
        public IObservable<T> Value { get; private set; }

        public string ValueText { get; set; }

        public ReturnExpression(ObservableFactory<IObservable<T>> value)
        {
            Contract.Requires(value != null);
            this.Value = Extract(value);
            EnabledProperty.Subscribe(x =>
            {
                foreach (var expr in this.MeAndAncestors())
                {
                    if (expr is IReactiveMethod)
                    {
                        var method = (ReactiveMethod<T>)expr;
                        if (x)
                            method.CurrentReturnExpression = this;
                        else if (method.CurrentReturnExpression == this)
                            method.CurrentReturnExpression = null;
                        break;
                    }

                    var parentBlock = expr.Parent as Block;
                    if (parentBlock != null)
                    {
                        if (x)
                            parentBlock.Disablers.Add(expr);
                        else
                            parentBlock.Disablers.Remove(expr);
                    }
                }
            });
        }

        public override string ToString()
        {
            string result = "return";
            if (typeof(T) != typeof(Unit))
                result += " " + (ValueText ?? Value.ToString());
            return result;

        }
    }
}
